package mrusanov.battle

import mrusanov.team.Team
import mrusanov.terrain.TerrainType

class MiniArena(val terrain:TerrainType, val battle:Battle) {
  private val CANNOT_SET_PLAYER_EX = "Cann't set player from team when there is " +
    "already player from this team on current mini-arena"
  private val OCCUPATION_TURNS_TO_WIN = 3

  private var _duelists:Map[Team, Option[PlayerState]] = Map()
  _duelists += (battle.hostTeam -> None)
  _duelists += (battle.guestTeam -> None)

  def duelists = _duelists

  private var _winningTeam:Option[Team] = None
  private var _countdownToWin = 0

  def winningTeam = _winningTeam
  def countdownToWin = _countdownToWin

  def getPlayer(team:Team):Option[PlayerState] = {
    require(battle.tookPartInBattle(team), "Illegal team, it doesn't take part in battle")
    duelists(team)
  }

  def addPlayer(player:PlayerState) {
    require(!isOver, "Duel is already isOver!")
    require(battle.tookPartInBattle(player.team), "Team must take part in battle")
    require(duelists(player.team) == None, CANNOT_SET_PLAYER_EX)



    val team = player.team
    _duelists += (team -> Some(player))
  }


  def removePlayer(player:PlayerState) {
    require(battle.tookPartInBattle(player.team), "Team must take part in battle")
    val team = player.team
    _duelists += (team -> None)
  }

  private def victoryByOccupation() {
    assume(!bothPresent && !empty)

    val (winningTeam, player) = duelists.filterNot(kv => kv._2 == None).head
    _winningTeam = Some(winningTeam)
  }

  def playRound():List[AttackInfo] = {
    require(_winningTeam == None, "Duel is already isOver, cann't play another round!")

    if (empty) {
      return Nil
    }

    if (!bothPresent) {
      _countdownToWin += 1
      if (_countdownToWin == OCCUPATION_TURNS_TO_WIN) {
        victoryByOccupation()
      }
      return Nil
    }

    val hostPlayer = duelists(battle.hostTeam).get
    val guestPlayer = duelists(battle.guestTeam).get

    val round = new PlayersDuelRound(this, hostPlayer, guestPlayer)
    val retList = round.fightRound()
    if (!hostPlayer.alive) {
      _duelists += (battle.hostTeam -> None)
      _winningTeam = Some(guestPlayer.team)
    }

    if (!guestPlayer.alive) {
      _duelists += (battle.guestTeam -> None)
      _winningTeam = Some(hostPlayer.team)
    }

    retList
  }

  def empty = duelists.values.forall(_ == None)
  def bothPresent = duelists.values.forall(_ != None)
  def isOver = _winningTeam.isDefined
  def isStarted = !isOver && !duelists.exists(_._2.isEmpty)

  def host = getPlayer(battle.hostTeam)
  def guest = getPlayer(battle.guestTeam)
}
